package ace.module.captcha.core.impl.manager.handler.impl;

import ace.cmp.easycaptcha.core.properties.EasyCaptchaProperties;
import ace.cmp.easycaptcha.core.service.EasyCaptchaFactory;
import ace.cmp.json.api.JsonService;
import ace.module.captcha.api.enums.CaptchaComponentConfigComponentTypeEnum;
import ace.module.captcha.core.impl.dao.entity.CaptchaComponentConfig;
import ace.module.captcha.core.impl.manager.handler.CaptchaImageHandler;
import ace.module.captcha.core.impl.manager.handler.model.dto.CaptchaImageBase64DataResultDto;
import ace.module.captcha.core.impl.manager.handler.model.dto.CaptchaImageStreamResultDto;
import com.wf.captcha.base.Captcha;
import java.io.ByteArrayOutputStream;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

/**
 * @author Caspar
 * @create 2020/11/5 验证码逻辑服务
 */
@Slf4j
@AllArgsConstructor
@Component
public class EasyCaptchaImageHandlerImpl implements CaptchaImageHandler {
  private final JsonService jsonService;
  private final EasyCaptchaProperties defaultProperties;
  private final EasyCaptchaFactory factory;

  @Override
  public Boolean support(CaptchaComponentConfig config) {
    return config == null
        || CaptchaComponentConfigComponentTypeEnum.EASY_CAPTCHA
            .getCode()
            .equals(config.getComponentType());
  }

  @Override
  public CaptchaImageStreamResultDto createImage(CaptchaComponentConfig config) {
    EasyCaptchaProperties properties = this.resolvePropertiesFromOrDefault(config);

    Captcha captcha = factory.create(properties);

    String code = captcha.text();

    ByteArrayOutputStream os = new ByteArrayOutputStream();

    captcha.out(os);

    return CaptchaImageStreamResultDto.builder().imageOutputStream(os).code(code).build();
  }

  @Override
  public CaptchaImageBase64DataResultDto createBase64Data(CaptchaComponentConfig config) {
    EasyCaptchaProperties properties = this.resolvePropertiesFromOrDefault(config);

    Captcha captcha = factory.create(properties);

    String code = captcha.text();

    String base64Data = captcha.toBase64();

    return CaptchaImageBase64DataResultDto.builder().base64Data(base64Data).code(code).build();
  }

  private EasyCaptchaProperties resolvePropertiesFromOrDefault(CaptchaComponentConfig config) {
    if (config == null || StringUtils.isEmpty(config.getConfig())) {
      return this.defaultProperties;
    }
    try {
      return this.jsonService.toObject(config.getConfig(), EasyCaptchaProperties.class);
    } catch (Exception ex) {
      log.error(String.format("captchaCategoryId:%s,配置解析失败", config.getId()), ex);
    }
    return this.defaultProperties;
  }
}
